#include <stdio.h>
#include <iostream>
#include <fstream>
#include "array_align.h"
#include <QtDebug>

using namespace std;

Array_align::Array_align(int size)
{
	int i;
	num_elements=0;
	max_size=size;
	A=new Align * [max_size];
	for(i=0; i<max_size; i++)
		A[i]=NULL;

}

Array_align::Array_align(Array_align * x)
{
	//replaces and existing Array_align with new Array_align x
	int i;

	max_size=x->get_num_elements();
	num_elements=0;
	A=new Align * [max_size];
	for(i=0; i<max_size; i++)
		A[i]=NULL;

	for(i=0; i<max_size; i++)
		add_align(x->A[i]);
}

Array_align::~Array_align()
{
	int i;
	for(i=0; i<num_elements; i++)
	{
		A[i]=NULL;
		delete A[i];
	}
	delete A;
	A=NULL;
}

int Array_align::get_num_elements(){return num_elements;}

bool Array_align::add_align(Align * a)
{
	if(num_elements>=max_size)
	{
		realloc();
	}

	if(A[num_elements]!=NULL)
	{
		delete a;
		a=NULL;
	}
	if(!is_in(a))
	{
		A[num_elements]=new Align(a);
		num_elements++;
	}

	return true;
}

bool Array_align::is_in(Align * a)
{
	int i;

	for(i=0; i<num_elements; i++)
	{
		if( (a->get_startSeq()==A[i]->get_startSeq()) && (a->get_endSeq()==A[i]->get_endSeq()) )
		{
			return true;
		}
	}
	return false;
}

Align Array_align::get_align(int i)
{
	Align * a;
	a=new Align(A[i]);
	return a;
}

bool Array_align::show_align()
{
	int i;
	cout << "startMono\tendMono\tstartSeq\tendSeq\tlengthAlign\tvalueAlign" << endl;
	for(i=0; i<num_elements; i++)
	{
		A[i]->show_align();
	}
	return true;
}

bool Array_align::realloc()
{
	Align ** temp=new Align * [max_size];
	int i;
	for(i=0; i<max_size; i++)
	{
		temp[i]=new Align(A[i]);
		delete [] A[i];
	}
	delete [] A;
	A=new Align * [max_size+10];
	for(i=0; i<max_size; i++)
	{
		A[i]=NULL;
		A[i]=new Align(temp[i]);
		delete [] temp[i];
	}

	max_size=max_size+10;
	while(i<max_size)
	{
		A[i]=NULL;
		i++;
	}
	delete [] temp;
	return true;
}

bool Array_align::sort()
{
	//sort by start position first and then by end position
	int i,j;
	int startSeq,endSeq;
	Align ** temp=new Align * [num_elements];
	bool * sort=new bool [num_elements];
	for(i=0; i<num_elements; i++) sort[i]=false;
	int minS,minE,index;

	for(i=0; i<num_elements; i++)
	{
		minS=100000000; minE=100000000;
		for(j=0; j<num_elements; j++)
		{
			startSeq=A[j]->get_startSeq();
			endSeq=A[j]->get_endSeq();
			if( (sort[j]==false) && (startSeq<=minS) )
			{
				if(startSeq!=minS)
				{
					minS=startSeq; minE=endSeq; index=j;
				}
				else
				{
					if(endSeq<=minE)
					{
						minS=startSeq; minE=endSeq; index=j;
					}
				}
			}
		}
		temp[i]=new Align(A[index]);
		sort[index]=true;
	}
	delete sort;

	for(i=0; i<num_elements; i++)
	{
		delete A[i];
		A[i]=new Align(temp[i]);
	}

	for(i=0; i<num_elements; i++)
	{
		delete [] temp[i];
	}
	delete [] temp;

	return true;
}

float Array_align::get_sum_sim()
{
	int i;
	float val=0;
	for(i=0; i<num_elements; i++)
		val=val+A[i]->get_valueAlign();
	return val;
}
